
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int H, W;
char s[N][N];
int startx, starty, endx, endy;
struct Node {
  int x, y, flag;
};
const int gox[] = {-1, 0, 1, 0}, goy[] = {0, -1, 0, 1};

int dis[N][N][2]; // dis[i][j][k] 到达（i，j） 棋盘状态为k的最短距离；

int bfs() {
  queue<Node> q;
  q.push(Node{startx, starty, 0});
  memset(dis, -1, sizeof(dis));
  dis[startx][starty][0] = 0;

  while (!q.empty()) {
    Node u = q.front();
    q.pop();
    if (u.x == endx && u.y == endy) {
      cout << dis[u.x][u.y][u.flag] << endl;
      return 1;
    }
    for (int i = 0; i < 4; ++i) {
      int sonx = u.x + gox[i], sony = u.y + goy[i];
      if (sonx >= 1 && sonx <= H && sony >= 1 && sony <= W &&
          s[sonx][sony] != '#') {
        if (u.flag == 0 && s[sonx][sony] == 'x')
          continue;
        if (u.flag == 1 && s[sonx][sony] == 'o')
          continue;

        int tflag = u.flag ^ (s[sonx][sony] == '?');
        Node v = {sonx, sony, tflag};
        if (dis[v.x][v.y][v.flag] == -1) {
          dis[v.x][v.y][v.flag] = dis[u.x][u.y][u.flag] + 1;
          q.push(v);
        }
      }
    }
  }
  return 0;
}
int main() {
  scanf("%d%d", &H, &W);
  for (int i = 1; i <= H; ++i) {
    scanf("%s", s[i] + 1);
    for (int j = 1; j <= W; ++j) {
      if (s[i][j] == 'S') {
        startx = i;
        starty = j;
      } else if (s[i][j] == 'G') {
        endx = i;
        endy = j;
      }
    }
  }
  if (!bfs())
    cout << -1 << endl;
  return 0;
}